﻿using AduSkin.Controls;
using AduSkin.Controls.Metro;
using DBMC_Core;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media.Imaging;

namespace DBMC
{
    /// <summary>
    /// AddMsaUser.xaml 的交互逻辑
    /// </summary>
    public partial class AddMsaUser : Window
    {
        private bool isDragging;
        private Point startPoint;
        MicrosoftOAuth oauth = new MicrosoftOAuth();
        Minecraft minecraft = new Minecraft();
        public string PlayerName, UUID, Access_Token, Refresh_Token;
        private bool IsPost = false;

        public AddMsaUser()
        {
            InitializeComponent();
            Loaded += delegate { LauncherCore.WriteLog($"启动器核心：添加微软账号 - 窗口打开正常"); };
            Closing += Window_Closing;
            GetDeviceCode();
        }

        private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
        {
            if (IsPost)
            {
                if (AduMessageBox.Show("要终止添加微软账号吗？", "关闭询问", MessageBoxButton.YesNo) == MessageBoxResult.No)
                {
                    LauncherCore.WriteLog($"启动器核心：添加微软账号 - 用户取消添加微软账号");
                    e.Cancel = true;
                }
            }
        }

        private void Window_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            isDragging = true;
            startPoint = e.GetPosition(this);
        }

        private void Window_MouseMove(object sender, MouseEventArgs e)
        {
            if (isDragging)
            {
                Point currentPoint = e.GetPosition(this);
                this.Left += currentPoint.X - startPoint.X;
                this.Top += currentPoint.Y - startPoint.Y;
            }
        }

        private void Window_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            isDragging = false;
        }

        private void ExitApp_Click(object sender, RoutedEventArgs e)
        {
            Close();
        }

        private async void GetDeviceCode()
        {
            LauncherCore.WriteLog($"启动器核心：添加微软账号 - 准备获取微软授权码");
            await Task.Delay(1000);
            IsPost = true;
            string content = oauth.GetDeviceCode();
            if (content != null)
            {
                // 解析JSON内容
                JObject json = JObject.Parse(content);
                string user_code = (string)json["user_code"];
                string device_code = (string)json["device_code"];
                string verification_uri = (string)json["verification_uri"];
                dynamic errorResponse = JsonConvert.DeserializeObject(content);
                // 更新UI线程
                await Application.Current.Dispatcher.InvokeAsync(() =>
                {
                    LauncherCore.WriteLog($"启动器核心：添加微软账号 - 已获取到微软授权码");
                    Clipboard.SetDataObject(user_code);
                    Code.Text = $"已自动复制，授权码：{user_code}";
                    Code.Visibility = Visibility.Visible;
                    try
                    {
                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 唤起浏览器中...");
                        System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
                        {
                            FileName = verification_uri,
                            UseShellExecute = true
                        });
                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 唤起浏览器成功");
                        NoticeManager.NotificationShow.AddNotification(new NotificationModel()
                        {
                            Title = "添加微软登录",
                            Content = $"授权码已复制，15分钟后过期，请在打开的浏览器页面中授权登录",
                            NotificationType = EnumPromptType.Info
                        });
                    }
                    catch (Exception)
                    {
                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 唤起浏览器失败");
                        NoticeManager.NotificationShow.AddNotification(new NotificationModel()
                        {
                            Title = "添加微软登录",
                            Content = $"打开浏览器失败，请安装浏览器后重试。",
                            NotificationType = EnumPromptType.Error
                        });
                    }
                });
                while (true)
                {
                    string DeviceCodeToken = await oauth.GetDeviceCodeToken(device_code);
                    if (DeviceCodeToken != null)
                    {
                        dynamic DeviceCodeTokenRes = JsonConvert.DeserializeObject(DeviceCodeToken);
                        if (DeviceCodeTokenRes?.access_token != null && DeviceCodeTokenRes?.refresh_token != null)
                        {
                            Refresh_Token = (string)DeviceCodeTokenRes?.refresh_token;
                            await Application.Current.Dispatcher.InvokeAsync(() =>
                            {
                                LauncherCore.WriteLog($"启动器核心：添加微软账号 - 用户已授权，获取数据中...");
                                Tips.Text = "用户已授权，添加中...";
                            });
                            await LoginAsync((string)DeviceCodeTokenRes.access_token);
                            return;
                        }

                        if (DeviceCodeTokenRes.error != null)
                        {
                            switch ((string)DeviceCodeTokenRes.error)
                            {
                                case "expired_token":
                                    await Application.Current.Dispatcher.InvokeAsync(() =>
                                    {
                                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 授权码已过期，将在3秒后重试");
                                        Tips.Text = "授权码已过期，将在3秒后重试";
                                    });
                                    await Task.Delay(3000);
                                    GetDeviceCode();
                                    break;
                                case "authorization_pending":
                                    await Application.Current.Dispatcher.InvokeAsync(() =>
                                    {
                                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 等待用户授权...");
                                        Tips.Text = "等待用户授权...";
                                    });
                                    break;
                                default:
                                    LauncherCore.WriteLog($"启动器核心：添加微软账号 - 未知错误");
                                    break;
                            }
                        }
                    }
                }
            }
            else
            {
                LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取授权码失败");
                NoticeManager.NotificationShow.AddNotification(new NotificationModel()
                {
                    Title = "添加微软登录",
                    Content = $"错误",
                    NotificationType = EnumPromptType.Error
                });
                Tips.Text = "请求错误，请稍后重试QAQ";
                IsPost = false;
            }
        }

        private async Task LoginAsync(string xboxtoken)
        {
            LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Xbox 令牌中...");
            //Console.WriteLine(xboxtoken);
            string XboxToken = await oauth.GetXboxToken(xboxtoken);
            if (XboxToken != null)
            {
                dynamic XboxTokenRes = JsonConvert.DeserializeObject(XboxToken);
                if (XboxTokenRes.Token != null)
                {
                    LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Xbox 令牌成功");
                    LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Xbox Xsts 令牌中...");
                    //Console.WriteLine("XboxToken", XboxTokenRes.Token);
                    string Xsts = await oauth.GetXsts((string)XboxTokenRes.Token);
                    if (Xsts != null)
                    {
                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Xbox Xsts 令牌成功");
                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Minecraft 令牌中...");
                        //Console.WriteLine("Xsts");
                        JObject jsonResponse = JObject.Parse(Xsts);
                        string token = jsonResponse["Token"].ToString();
                        string uhs = jsonResponse["DisplayClaims"]["xui"][0]["uhs"].ToString();
                        if (uhs != null && token != null)
                        {
                            string MinecraftToken = await oauth.GetMinecraftToken(uhs, token);
                            if (MinecraftToken != null)
                            {
                                LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Minecraft 令牌成功");
                                LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Minecraft 档案信息中...");
                                //Console.WriteLine("MinecraftToken");
                                dynamic MinecraftTokenRes = JsonConvert.DeserializeObject(MinecraftToken);
                                if (MinecraftTokenRes.access_token != null)
                                {
                                    Access_Token = MinecraftTokenRes.access_token;
                                    string MinecraftProfile = await oauth.GetMinecraftProfile((string)MinecraftTokenRes.access_token);
                                    if (MinecraftProfile != null)
                                    {
                                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 获取 Minecraft 档案信息成功");
                                        //Console.WriteLine("MinecraftProfile");
                                        dynamic MinecraftProfileRes = JsonConvert.DeserializeObject(MinecraftProfile);
                                        if (MinecraftProfileRes.name != null && MinecraftProfileRes.id != null)
                                        {
                                            IsPost = false;
                                            PlayerName = (string)MinecraftProfileRes.name;
                                            UUID = (string)MinecraftProfileRes.id;
                                            Application.Current.Dispatcher.Invoke(() =>
                                            {
                                                LoadHead((string)MinecraftProfileRes.name);
                                                Tips.Text = (string)MinecraftProfileRes.name;
                                            });
                                            await Task.Delay(2000);
                                            Application.Current.Dispatcher.Invoke(() =>
                                            {
                                                DialogResult = true;
                                                Close();
                                            });
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }

        private BitmapImage DecodeImageFromBase64(string base64String)
        {
            BitmapImage image = new BitmapImage();
            if (!string.IsNullOrEmpty(base64String))
            {
                byte[] imageBytes = Convert.FromBase64String(base64String);
                using (MemoryStream memStream = new MemoryStream(imageBytes))
                {
                    image.BeginInit();
                    image.CacheOption = BitmapCacheOption.OnLoad;
                    image.StreamSource = memStream;
                    image.EndInit();
                    image.Freeze(); // 因为是在非UI线程使用UI资源，所以进行冻结
                }
            }
            return image;
        }

        private void LoadHead(string name)
        {
            LauncherCore.WriteLog($"启动器核心：添加微软账号 - 加载头像中");
            // 文件缓存目录
            string cacheDir = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Temp", "DBMC", "MCImageCache");
            string cacheFile = Path.Combine(cacheDir, $"{name}.png");

            // 检查缓存是否存在且有效
            if (File.Exists(cacheFile) && (DateTime.Now - File.GetLastWriteTime(cacheFile)).TotalDays < 1)
            {
                // 从本地缓存加载图像
                BitmapImage image = new BitmapImage(new Uri(cacheFile));
                HeadSkin.Source = image;
                LauncherCore.WriteLog($"启动器核心：添加微软账号 - 已从缓存加载头像");
            }
            else
            {
                // 尝试从网络加载图像
                BitmapImage image = new BitmapImage();

                try
                {
                    image.BeginInit();
                    image.UriSource = new Uri("https://mineskin.eu/helm/" + $"{name}" + "/100.png", UriKind.Absolute);
                    image.CacheOption = BitmapCacheOption.OnLoad; // 设置缓存选项
                    image.DownloadCompleted += (s, e) =>
                    {
                        // 图像下载成功，保存到本地缓存
                        SaveImageToCache(image, cacheDir, cacheFile);
                    };
                    image.DownloadFailed += (s, e) =>
                    {
                        // 如果下载失败，使用默认的Base64编码的图像
                        image = DecodeImageFromBase64(Danbai.HandImage);
                        Loading.Visibility = Visibility.Hidden;
                        UserHeadImage.Visibility = Visibility.Visible;
                        HeadSkin.Source = image;
                        LauncherCore.WriteLog($"启动器核心：添加微软账号 - 加载头像失败，使用默认图像");
                    };
                    image.EndInit();
                    Loading.Visibility = Visibility.Hidden;
                    UserHeadImage.Visibility = Visibility.Visible;
                    HeadSkin.Source = image;
                    LauncherCore.WriteLog($"启动器核心：添加微软账号 - 已从网络加载头像");
                }
                catch
                {
                    // 如果在初始化图像期间发生异常，使用Base64默认图像
                    image = DecodeImageFromBase64(Danbai.HandImage);
                    HeadSkin.Source = image;
                    Loading.Visibility = Visibility.Hidden;
                    UserHeadImage.Visibility = Visibility.Visible;
                    HeadSkin.Source = image;
                    LauncherCore.WriteLog($"启动器核心：添加微软账号 - 加载头像失败，使用默认图像");
                }
            }
        }

        // 保存图像到本地缓存
        private void SaveImageToCache(BitmapSource image, string cacheDir, string cacheFile)
        {
            if (!Directory.Exists(cacheDir))
            {
                Directory.CreateDirectory(cacheDir);
            }

            using (var fileStream = new FileStream(cacheFile, FileMode.Create))
            {
                BitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(image));
                encoder.Save(fileStream);
                LauncherCore.WriteLog($"启动器核心：添加微软账号 - 头像已经缓存");
            }
        }

    }
}